import os from "os";
import child_process from "child_process";

type CmdAnswer = {
  pid?: number;
  text?: string;
};

import tree_kill from "tree-kill";
import iconv_lite from "iconv-lite";

/** 获取本机局域网适配器信息 */
type LocalNetworkData = { ip: string; family: string; device: string };
export function getLocalNetworkIPs(): LocalNetworkData[] {
  const results: LocalNetworkData[] = [];
  const interfaces = os.networkInterfaces();
  for (const device_name in interfaces) {
    const datas = interfaces[device_name];
    datas?.map((data) => {
      const isVerified = data.family === "IPv4" && data.address !== "127.0.0.1";
      isVerified && results.push({ ip: data.address, family: data.family, device: device_name });
    });
  }

  return results;
}

/** 执行一个CMD任务 */
export function excuteCmd(command: string, answer: (CmdAnswer: CmdAnswer) => void, stdout: boolean = true): number {
  // 终止敏感操作
  command = command.replace(/\n|\s/g, " ");
  if (_isDanger(command)) {
    answer({
      pid: -1,
      text: `@main/${process.pid} refuse danger command: ${command}`,
    });
    return -1;
  }

  // 通过子进程执行命令
  const SubProcess = child_process.exec(
    command,
    { maxBuffer: 1024 * 1024 * 1024 },
    // 执行结束时的回调
    (error: child_process.ExecException | null, stdout: string, stderr: string) => {
      const Title = `@process:${process.pid} @sub_process:${SubProcess.pid}`;
      const Answer: CmdAnswer = {
        pid: -1,
        text: `${Title} success! ✅`,
      };

      if (error) Answer.text = `@process:${process.pid} command error:${error?.message}`;
      else if (stderr) Answer.text = `@sub_process:${SubProcess.pid} error:${stderr}`;

      answer(Answer);
    },
  );

  // 首次回应请求者
  const Encoding = "latin1"; // 默认 utf8 latin1/binary SubProcess.stdout.readableEncoding
  SubProcess.stdout?.setEncoding(Encoding);
  const Decoding = "utf8"; // cp936 utf8
  const Title = `@sub_process:${SubProcess.pid} start：${Encoding}=>${Decoding}`;
  answer({ pid: SubProcess.pid, text: Title });

  // 持续回应请求者
  stdout &&
    SubProcess.stdout?.on("data", (message) => {
      const Text = iconv_lite.decode(Buffer.from(`@sub_process:${SubProcess.pid}:log ${message}`, Encoding), Decoding);
      answer({
        pid: SubProcess.pid,
        text: Text,
      });
      if (message.includes("Merge conflict")) killCmd(SubProcess.pid as number); // 进程终止会触发进程的error事件
    });

  return SubProcess.pid as number;
}

/** 销毁进程 */
export function killCmd(processId: number): void {
  tree_kill(processId);
}

/** 辅助方法 */
function _isDanger(command: string): boolean {
  command = command.trim().toUpperCase();
  let result = false;
  if (command.length === 0) result = true;
  if (command.indexOf("SSH") >= 0) result = true;
  return result;
}
